import 'dart:io';

import 'package:dio/dio.dart' as dio;
import 'package:get/get.dart';
import 'package:largefriends/entity/entities/lf_relation_result_entity.dart';
import 'package:largefriends/net/lf_api_url.dart';
import 'package:largefriends/net/lf_dio_util.dart';
import 'package:largefriends/pages/lf_home/lf_home_logic.dart';
import 'package:largefriends/res/lf_string_ext.dart';
import 'package:largefriends/service/lf_auth_service.dart';
import 'package:largefriends/widgets/check_hidden.dart';

import '../entity/entities/lf_bool_entity.dart';
import '../entity/entities/lf_photo_entity.dart';
import '../entity/entities/lf_user_entity.dart';
import '../events/delete_badge_count.dart';
import '../events/delete_conversation_event.dart';
import '../events/timeline_action_event.dart';
import '../events/user_relation_event.dart';
import '../service/manager/lf_event_helper.dart';
import '../service/manager/lf_user_cache_manager.dart';
import '../res/strings/lf_strings.dart';
import '../utils/lf_dialog_utils.dart';
import '../widgets/dialog_action_tip.dart';
import 'error_handle.dart';

Future<LfPhotoEntity?> uploadAudio(
  File file,
  int duration,
) async {
  var formData = dio.FormData();
  var multiFile = await dio.MultipartFile.fromFile(
    file.path,
  );
  formData.files.add(
    MapEntry(
      'file',
      multiFile,
    ),
  );
  formData.fields.add(MapEntry('duration', '$duration'));
  var result = await LfDio()
      .post<List<LfPhotoEntity>>(
    url: apiUploadFile,
    params: formData,
    // onSendProgress: onSendProgress,
  )
      .then((value) {
    if (value.isNotEmpty) {
      return Future(() => value.first);
    } else {
      ///先不用管,正常情况下不会走此处,除非服务器乱改结构
      throw ExceptionHandle.handleException(value);
    }
  }, onError: (value) {
    if (value is NetError) {
      throw value;
    }

    ///先不用管,正常情况下不会走此处,除非服务器乱改结构
    throw value;
  });

  ///先不用管,正常情况下不会走此处,
  return result;
}

Future blockUser({required String uid}) async {
  showActionTips(
      tips: strBlockTip.tr,
      actionButtonTip: strBlock.tr,
      action: () async {
        await _blockUserRequest(uid: uid);
      });
}

Future _blockUserRequest({required String uid}) async {
  // showLoading();
  await LfDio().post<LfBoolEntity>(
    url: apiBlockUser,
    params: {
      'userId': uid,
    },
  ).then((value) {
    hideLoading();
    LfUserCacheManager().setCacheUser(key: uid, user: null);

    ///清除cache
    LfEventHelper()
        .getEvent()
        .fire(UserRelationEvent(uid: uid, type: UserRelationType.block));
  }, onError: (error) {
    hideLoading();
    if (error is NetError) {
      showSnackBar(error.msg);
    }
  });
}

Future likeUser({required LfUserEntity user}) async {
  checkHidden(() async {
    LfAuthService authService = Get.find();
    if (authService.canLike()) {
      showLoading();
      await LfDio().post<LfRelationResultEntity>(
        url: apiLikeUser,
        params: {
          'userId': user.userId,
        },
      ).then((value) {
        hideLoading();
        LfAuthService authService = Get.find();
        authService.currentSparkCnt = value.sparkCntToday;
        authService.currentLikeCnt = value.likedCntToday;
        LfEventHelper().getEvent().fire(UserRelationEvent(
            uid: user.userId!, type: UserRelationType.like, userEntity: user));
      }, onError: (error) {
        hideLoading();
        if (error is NetError) {
          showSnackBar(error.msg);
        }
      });
    } else {
      // showLikeLimitTips(userEntity: user); TODO
    }
  });
}

Future unlikeUser({required LfUserEntity user}) async {
  showActionTips(
      tips:
          strUnlikeTip.tr.replacePercentS([user.username.toUpperCase()]) ?? "",
      actionButtonTip: strSure.tr,
      action: () async {
        await _unlikeUserAction(user: user);
      });
}

Future _unlikeUserAction({required LfUserEntity user}) async {
  // showLoading();
  await LfDio().post<LfBoolEntity>(
    url: apiUnLikeUser,
    params: {
      'userId': user.userId,
    },
  ).then((value) {
    hideLoading();
    LfEventHelper().getEvent().fire(UserRelationEvent(
        uid: user.userId!, type: UserRelationType.unlike, userEntity: user));
  }, onError: (error) {
    hideLoading();
    if (error is NetError) {
      showSnackBar(error.msg);
    }
  });
}

Future likeTimeLine({required String timelineId}) async {
  // showLoading();
  await LfDio().post<LfBoolEntity>(
    url: apiLikeTimeline,
    params: {
      'timelineId': timelineId,
    },
  ).then((value) {
    hideLoading();
    LfEventHelper().getEvent().fire(TimelineActionEvent(
        timelineId: timelineId, action: TimelineAction.like));
  }, onError: (error) {
    hideLoading();
    if (error is NetError) {
      showSnackBar(error.msg);
    }
  });
}

Future unlikeTimeLine({required String timelineId}) async {
  // showLoading();
  await LfDio().post<LfBoolEntity>(
    url: apiDisLikeTimeline,
    params: {
      'timelineId': timelineId,
    },
  ).then((value) {
    hideLoading();
    LfEventHelper().getEvent().fire(TimelineActionEvent(
        timelineId: timelineId, action: TimelineAction.unlike));
  }, onError: (error) {
    hideLoading();
    if (error is NetError) {
      showSnackBar(error.msg);
    }
  });
}

Future deleteTimeline({required String timelineId}) async {
  showActionTips(
      tips: strDeleteMomentTip.tr,
      actionButtonTip: strSure.tr,
      action: () async {
        await _deleteTimelineAction(timelineId: timelineId);
      });
}

Future _deleteTimelineAction({required String timelineId}) async {
  // showLoading();
  await LfDio().post<LfBoolEntity>(
    url: apiDeleteTimeline,
    params: {
      'timelineId': timelineId,
    },
  ).then((value) {
    hideLoading();
    LfEventHelper().getEvent().fire(TimelineActionEvent(
        timelineId: timelineId, action: TimelineAction.delete));
  }, onError: (error) {
    hideLoading();
    if (error is NetError) {
      showSnackBar(error.msg);
    }
  });
}

Future sendWink({required LfUserEntity userEntity}) async {
  // checkHidden(() async {
  //   LfAuthService authService = _get.Get.find();

  //   if (authService.canWink()) {
  //     var entity = LfWinkEntity(descr: strSendWinkDes.tr, id: '3');

  //     ///直接写死某个wink
  //     showWinkDialog();
  //     await LfDio.instance.post<LfBoolEntity>(url: apiSendWink, params: {
  //       'profId': userEntity.userId,
  //       'userId': authService.currentAccount!.userId,
  //       'winkedType': entity.id
  //     }).then((value) {
  //       hideLoading();
  //       authService.currentWinkCnt++;
  //       LfEventHelper().getEvent().fire(UserRelationEvent(
  //           uid: userEntity.userId ?? "", type: UserRelationType.wink));
  //     }, onError: (error) {
  //       hideLoading();
  //       if (error is NetError) {
  //         showSnackBar(error.msg);
  //       }
  //     });
  //   } else {
  //     showWinkLimitTips(userEntity: userEntity);
  //   }
  // });
}

Future deleteConversation({required String uid}) async {
  // showLoading();
  LfDio.instance.post<LfBoolEntity>(
      url: apiDeleteConversation, params: {'profId': uid}).then((value) {
    hideLoading();
    LfEventHelper().getEvent().fire(DeleteConversationEvent(uid: uid));
  }, onError: (error) {
    hideLoading();
    if (error is NetError) {
      showSnackBar(error.msg);
    }
  });
}

Future deleteNotificationBadge(
    {required String uid, required BadgeChangeType type}) async {
  Map<String, dynamic> params = {};
  params.putIfAbsent('type', () => type.value);
  params.putIfAbsent('userIds', () => uid);
  LfDio.instance.post<LfBoolEntity>(url: apiDeleteBadge, params: params).then(
      (value) {
    LfEventHelper()
        .getEvent()
        .fire(DeleteBadgeCountEvent(type: type, uid: uid));
  }, onError: (error) {
    //do nothing
  });
}

Future requestPrivatePhoto(LfUserEntity userEntity) async {
  checkHidden(() async {
    showLoading();
    LfDio.instance.post<LfBoolEntity>(
        url: apiRequestPrivatePhoto,
        params: {'userId': userEntity.userId}).then((value) {
      hideLoading();
      LfEventHelper().getEvent().fire(UserRelationEvent(
          uid: userEntity.userId!, type: UserRelationType.requestPrivate));
    }, onError: (error) {
      hideLoading();
      if (error is NetError) {
        showSnackBar(error.msg);
      }
    });
  });
}
